package com.jh.paymentchannel.payment;

import cn.jh.common.utils.CommonsUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.google.common.base.Joiner;
import com.jh.paymentchannel.business.PaymentOrderBusiness;
import com.jh.paymentchannel.payment.alipay.AlipayConfig;
import com.jh.paymentchannel.payment.wechat.WechatConfig;
import com.jh.paymentchannel.payment.wechat.WechatUtil;
import com.jh.paymentchannel.pojo.PaymentOrder;
import com.jh.paymentchannel.pojo.PaymentView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

import static io.jsonwebtoken.lang.Strings.hasText;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * @author Yichuan
 * @version 1.0
 */
@RestController
public class PaymentController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PaymentController.class);

    private final PaymentOrderBusiness paymentOrderBusiness;
    private final WechatConfig wechatConfig;
    private final AlipayConfig alipayConfig;

    @Autowired
    public PaymentController(PaymentOrderBusiness paymentOrderBusiness, WechatConfig wechatConfig, AlipayConfig alipayConfig) {
        this.paymentOrderBusiness = paymentOrderBusiness;
        this.wechatConfig = wechatConfig;
        this.alipayConfig = alipayConfig;
    }

    @Value("${platform.outPutPath}")
    private String outPutPath;

    /**
     * 订单创建接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/order/create", method = POST)
    public Object order(PaymentRequest paymentRequest, HttpServletRequest request) {
        String message = paymentRequest.valid();
        if (hasText(message)) {
            return CommonsUtil.returnError(message);
        }
        try {
            paymentRequest.setIp(PaymentUtils.getIPAddress(request));
            if (paymentRequest.isAlipay()) {
                // 支付宝手机H5网页支付
                //String result = paymentOrderBusiness.createAlipayOrder(paymentRequest);
                //return CommonsUtil.returnSuccess("成功", result);
                // 支付宝授权扫码支付
                AlipayTradePrecreateResponse precreateResponse = paymentOrderBusiness.alipayPrecreateOrder(paymentRequest);
                if (precreateResponse == null) {
                    return CommonsUtil.returnError("订单创建失败");
                }
                return CommonsUtil.returnOK(precreateResponse.getQrCode());
            } else if (paymentRequest.isWechat()) {
                Map<String, String> result = paymentOrderBusiness.createWechatOrder(paymentRequest);
                return CommonsUtil.returnSuccess("成功", result);
            } else {
                return CommonsUtil.returnError("支付渠道不存在");
            }
        } catch (PaymentException ex) {
            return CommonsUtil.returnError(ex.getMessage());
        }
    }

    /**
     * 微信获取code的接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/wechat/redirect", method = POST)
    public Object getWechatRedirect(PaymentRequest paymentRequest, HttpServletRequest request) {
        return CommonsUtil.returnSuccess("成功", WechatConfig.getRedirectUrl(wechatConfig.getRedirectUri(), paymentRequest));
    }

    /**
     * 订单查询接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/order/query", method = GET)
    public Object findPaymentOrder(@RequestParam("outTradeNo") String outTradeNo) {
        PaymentOrder paymentOrder = paymentOrderBusiness.findPaymentOrder(outTradeNo);
        if (paymentOrder == null) {
            return CommonsUtil.returnError("订单信息不存在");
        }
        return CommonsUtil.returnOK(PaymentOrderDTO.order(paymentOrder));
    }

    /**
     * 支付宝回调接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/order/alipay/callback", method = POST, produces = "text/plain")
    public String alipayCallback(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestData = request.getParameterMap();
        for (Map.Entry<String, String[]> entry: requestData.entrySet()) {
            params.put(entry.getKey(), Joiner.on("").join(entry.getValue()));
        }
        try {
            paymentOrderBusiness.notifyPaymentOrder(params, OrderType.ALIPAY);
        } catch (PaymentException e) {
            e.printStackTrace();
            return "failure";
        }
        return "success";
    }

    /**
     * 微信回调接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/order/wechat/callback", method = POST, produces = "text/plain")
    public String wechatCallback(HttpServletRequest request) {
        try {
            String inputLine;
            StringBuilder notifyXml = new StringBuilder();
            while ((inputLine = request.getReader().readLine()) != null) {
                notifyXml.append(inputLine);
            }
            request.getReader().close();

            System.out.println("接收到的报文：" + notifyXml.toString());
            Map<String, String> params = WechatUtil.xmlToMap(notifyXml.toString());

            boolean isSignPass = WechatUtil.isSignatureValid(params, wechatConfig.getApiSecret(), WechatUtil.SignType.HMACSHA256);
            if (!isSignPass) {
                LOGGER.error("************微信签名验证失败***********数据：" + JSON.toJSONString(params));
                return WechatUtil.returnFail("签名验证失败");
            }
            paymentOrderBusiness.notifyPaymentOrder(params, OrderType.WECHAT);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            return WechatUtil.returnFail("失败");
        }
        return WechatUtil.returnSuccess();
    }

    /**
     * 订单补单接口
     */
    @RequestMapping(value = "/v1.0/paymentchannel/order/supply", method = POST)
    public Object supplyOrder(@RequestParam("outTradeNo") String outTradeNo) {
        if (!hasText(outTradeNo)) {
            return CommonsUtil.returnError("支付订单号不能为空");
        }
        PaymentOrder paymentOrder;
        try {
            paymentOrder = paymentOrderBusiness.supplyPaymentOrder(outTradeNo);
            if (paymentOrder == null) {
                return CommonsUtil.returnError("订单补单失败");
            }
        } catch (PaymentException ex) {
            return CommonsUtil.returnError(ex.getMessage());
        }
        return CommonsUtil.returnOK(paymentOrder);
    }


    @RequestMapping(value = "/v1.0/paymentchannel/order", method = POST)
    public Object addOrder(PaymentView view) {
        paymentOrderBusiness.addPayment(view);
        return CommonsUtil.returnOK();
    }
}
